Страницы свойств реализуються как отдельные COM объекты, это позволяют страницам свойств быть общедоступными если необходимо. Чтобы добавить страницу свойств к вашему элементу управления Вы можете использовать ATL Object Wizard.
Запустите ATL Object Wizard и выберите Controls с левой стороны из групп. Выберите страницу свойств (Property Page) и нажмите Next. Выберите страницу свойств (Property Page) и нажмите Next. Вы увидите диалоговое окно которое позволяет Вам ввести имя нового объекта. Назовем объект PolyProp и введем его имя в окно редактирования Short Name.

Обратите внимание, что окно Interface недоступно. Это потому что страница свойств не нуждается в заказном интерфейсе.
Нажмите на вкладку Strings чтобы установить заголовок страницы свойств. Заголовок страницы свойств - строка которая появляется на вкладке. Напечатайте $Polygon как заголовок. Doc String - описание которое рамка свойства использует чтобы поместить в строку состояния или совет в панели инструментов. Обратите внимание что стандартная страница свойств в настоящее время не использует эту строку, но Вы можете устанавливать ее в любом случае. Вы не собираетесь генерировать Helpfile в настоящее время, сотрите этот текстовой блок. Нажмите OK и объект страницы свойств будет создан.

Следующие три файла будут созданы:
PolyProp.h Содержит C++ класс CPolyProp который осуществляет страницу свойств. PolyProp.cpp Включает PolyProp.h файл. PolyProp.rgs Сценарий регистрации который регистрирует объект страницы свойств.
Сделаны следующие изменения кода:
1. Новая страница свойств добавлена в
объектную карту в Polygon.cpp.
2. Класс PolyProp добавлен в
Polygon.idl файл.
3. Новый файл сценария регистрации в реестре
PolyProp.rgs добавлен в ресурсы проекта.
4. Шаблон диалогового окна
добавлен к ресурсу проекта для страницы свойств.
5. Строки свойств которые Вы
определили, добавлены в таблицу строк ресурсов.
Теперь добавьте поля которые Вы хотите видеть на странице свойств. Обратите внимание, что в Polygon.rc диалог пуст кроме метки которая сообщает чтобы Вы может вставили ваши средства управления в этом месте. Удалите эту метку и добавьте метку которая содержит текст "Sides:". Рядом с меткой добавьте окно редактирования с идентификатором IDC_SIDES.

Включите Polygon.h вверху PolyProp.h файла:
#include "Polygon.h" // definition of IPolyCtl
Теперь дайте возможность классу CPolyProp установить число сторон в вашем объекте когда кнопка Apply нажата. Измените функцию Apply в PolyProp.h следующим образом.
STDMETHOD(Apply)(void)
{
USES_CONVERSION;
ATLTRACE(_T("CPolyProp::Apply\n"));
for (UINT i = 0; i < m_nObjects; i++)
{
CComQIPtr<IPolyCtl, &IID_IPolyCtl> pPoly(m_ppUnk[i]);
short nSides = (short)GetDlgItemInt(IDC_SIDES);
if FAILED(pPoly->put_Sides(nSides))
{
CComPtr<IErrorInfo> pError;
CComBSTR strError;
GetErrorInfo(0, &pError);
pError->GetDescription(&strError);
MessageBox(OLE2T(strError), _T("Error"), MB_ICONEXCLAMATION);
return E_FAIL;
}
}
m_bDirty = FALSE;
return S_OK;
}
Страница свойств может иметь несколько клиентов одновременно, поэтому функция Apply вызывает put_Sides каждого клиента со значением полученным из окна редактирования. Вы используете CComQIPtr класс, который выполняет QueryInterface для каждого объекта чтобы получить интерфейс IPolyCtl из IUnknown (сохраненный в m_ppUnk массиве).
Код теперь проверяет что установка свойства фактически произошла. Если установка свойств терпит неудачу, код отображает подробности ошибки отображая окно сообщения из интерфейса IErrorInfo. Обычно, контейнер спрашивает объект относительно интерфейса ISupportErrorInfo и вызывает InterfaceSupportsErrorInfo что бы определить, поддерживает ли объект данные об ошибках. Но так как это - ваш элемент управления Вы можете пропустить эту проверку.
CComPtr помогает Вам автоматически обрабатывая подсчет ссылки, в результате Вы не должны вызвать Release. CComBSTR помогает Вам с обработкой BSTR, в результате Вам не надо выполнять обращение SysFreeString. Вы также используете строковые преобразования, по этой причине добавлена макрокоманда USES_CONVERSION в начале функции
Вы также должны создать флажок для страницы свойств чтобы указать что к кнопке Apply нужно разрешить доступ. Доступ нужно разрешать когда пользователь изменяет значение в окне редактирования Side. Щелкните правой кнопкой мыши класс страницы свойств в ClassView, и затем выберите Add Windows Message Handler... из контекстного меню. Выберите IDC_SIDES из списка и затем добавьте EN_CHANGE сообщение.
Теперь добавьте следующий код в Polyprop.h к функции OnChangeSides. (удалите любой код который там поместил мастер):
LRESULT OnChangeSides(WORD wNotify, WORD wID, HWND hWnd, BOOL& bHandled)
{
SetDirty(TRUE);
return 0;
}
OnChangeSides будет вызываться когда WM_COMMAND сообщение послано с EN_CHANGE уведомлением для элемента управления IDC_SIDES. OnChangeSides затем вызываем SetDirty и передаем TRUE чтобы указать что страница свойств теперь изменена и кнопку Apply нужно разрешить. Давайте добавим страницу свойств к вашему элементу управления. ATL Object Wizard не делает это автоматически с тех пор как в вашем проекте несколько элементов управления.
Откройте PolyCtl.h и добавьте эту строку в карту свойств:
PROP_ENTRY("Sides", 1, CLSID_PolyProp)
Карта свойств элемента управления теперь выглядит следующим образом:
BEGIN_PROP_MAP(CPolyCtl)
PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4)
PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4)
PROP_ENTRY("FillColor", DISPID_FILLCOLOR, CLSID_StockColorPage)
PROP_ENTRY("Sides", 1, CLSID_PolyProp)
// Example entries
// PROP_ENTRY("Property Description", dispid, clsid)
// PROP_PAGE(CLSID_StockColorPage)
END_PROP_MAP()
Вы могли бы добавить макрокоманду PROP_PAGE с CLSID вашей страницы свойств, но если Вы используете макрокоманду PROP_ENTRY как показано, значение свойства Sides будет сохранено когда элемент управления сохранен. Три параметра для макрокоманды - описание свойства, DISPID свойства, CLSID страницы свойств. Это полезно если например Вы загружаете элемент управления в VB и устанавливаете число Sides во время разработки. Так как число Sides сохранено, когда Вы перезагружаете ваш VB проект, число Sides будет автоматически восстановлено.
Соберите элемент управления и вставьте его в ActiveX Control Test Container. Затем в меню Edit нажимаем PolyCtl Class Object. Страница свойств появится, выберите вкладку Polygon.

Кнопка Apply первоначально заблокирована. Начните печатать значение в окне редактирования Side и кнопка Apply станет доступной. После того, как Вы закончили вводить значение нажмите кнопку Apply. Элемент управления будет изменен и кнопка Apply снова заблокирована. Пробуйте вводить недопустимое значение и Вы должны видеть окно сообщения содержащее описание ошибки из функции put_Sides.